package cn.stimd.spring.format.datetime;

import cn.stimd.spring.format.Formatter;
import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Stimd
 * 项目地址：https://gitee.com/stimd/spring-wheel
 * 公众号：Java编程探微
 */
public class DateFormatter implements Formatter<Date> {
    private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
    private static final Map<ISO, String> ISO_PATTERNS;

    static {
        Map<ISO, String> formats = new EnumMap<>(ISO.class);
        formats.put(ISO.DATE, "yyyy-MM-dd");
        formats.put(ISO.TIME, "HH:mm:ss.SSSZ");
        formats.put(ISO.DATE_TIME, "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        ISO_PATTERNS = Collections.unmodifiableMap(formats);
    }

    private String pattern;
    private int style = DateFormat.DEFAULT;
    private ISO iso;

    public DateFormatter() { }

    public DateFormatter(String pattern) {
        this.pattern = pattern;
    }


    @Override
    public Date parse(String text, Locale locale) throws ParseException {
        return getDateFormat(locale).parse(text);
    }

    @Override
    public String print(Date date, Locale locale) {
        return getDateFormat(locale).format(date);
    }

    protected DateFormat getDateFormat(Locale locale) {
        //使用指定的pattern
        if (StringUtils.hasLength(this.pattern)) {
            return new SimpleDateFormat(this.pattern, locale);
        }

        //
        if (this.iso != null && this.iso != ISO.NONE) {
            String pattern = ISO_PATTERNS.get(this.iso);
            if (pattern == null) {
                throw new IllegalStateException("Unsupported ISO format " + this.iso);
            }
            SimpleDateFormat format = new SimpleDateFormat(pattern, locale);
            format.setTimeZone(UTC);
            return format;
        }

        return DateFormat.getDateInstance(this.style, locale);
    }

    public void setPattern(String pattern) {
        this.pattern = pattern;
    }
    public void setIso(ISO iso) {
        this.iso = iso;
    }
    public void setStyle(int style) {
        this.style = style;
    }

    public enum ISO {
        DATE, TIME, DATE_TIME, NONE
    }
}
